# ----------------------------------------------------------------------------
#       Copyright (C) 2013-2014 Huynh Vi Lam  <domovilam@gmail.com>
#
#       This file is part of pimucha.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Generic Net Controllers
# Receiving  and Sending data over Network 
# Python version 2.7.x and 3.x
# ----------------------------------------------------------------------------

import logging,socket,sys,time
from piHAlibs import addr2host

logger = logging.getLogger()

class NETCTRL(object):

    def __init__(self,defaddr=None,rxaddr=None,txaddr=None):
        if defaddr is None: defaddr = ('localhost','9000')
        self.name = 'NETC'
        self.rxaddr = rxaddr
        self.txaddr = txaddr
        self.opened = False
        self.setup = False
        self.stop = False
        if self.rxaddr:
            self.rxhost,self.rxport = addr2host(defaddr=defaddr,addr=self.rxaddr)
            self.rxsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.txaddr:
            self.txhost,self.txport = addr2host(defaddr=defaddr,addr=self.txaddr)
            self.txsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def rxopen(self):
        try:
            self.rxsock.connect((self.rxhost,self.rxport))
            logger.debug("Server host RX %s is up",repr((self.rxhost,self.rxport)))
            self.rxsock.settimeout(1)
            return True
        except:
            logger.debug("Server host RX %s is down",repr((self.rxhost,self.rxport)))
            self.close()
            return False

    def txopen(self):
        try:
            self.txsock.connect((self.txhost,self.txport))
            logger.debug("Server host TX %s is up",repr((self.txhost,self.txport)))
            self.txsock.close()
            return True
        except:
            logger.debug("Server host TX %s is down",repr((self.txhost,self.txport)))
            self.setup = False
            return False

    def open(self):
        if self.rxaddr :
            if self.rxopen() : self.opened = True
        if self.txaddr :
            if self.txopen() : self.opened = True

    def close(self):
        if self.rxaddr:
            self.rxsock.close()
        if self.txaddr:
            self.txsock.close()
        self.opened = False

    def tsetup(self):
        self.open()
        if self.opened:
            self.setup = True
            return True
        else:
            return False

    def rxevent(self):
        received = None
        try:
            received = self.rxsock.recv(1024)
        except Exception as e:
            if str(e) != 'timed out':
                logger.critical("%s : %s" ,repr(e.__class__), str(e))
                self.setup = False
                self.close()
                return None
        if received is None: return None
        events = []
        for e in received.split("\n")[:-1]:
            if e not in events:
                events.append(e)
        if len(events) !=0 :
            logger.debug("%s" , repr(events))
            return '|'.join(events)
        return None
 
    def netsend(self,data):
        if isinstance(data,bytes):
            data += b"\n"
        else:
            data = ((data + "\n").encode('utf-8'))
        txsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        txsock.settimeout(3.0)
        try:
            txsock.connect((self.txhost,self.txport))
            txsock.sendall(data)
            received = txsock.recv(1024)
            logger.info("Received from %s : %s" ,repr((self.txhost,self.txport)), repr(received))
            return True
        except Exception as e:
            logger.critical("%s : %s" ,repr(e.__class__), str(e))
            return False
        finally:
            txsock.close()

